package com.christina.engine.processing.impl;

import com.christina.engine.intent.model.Intent;
import com.christina.engine.processing.AbstractRequestProcessor;
import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingResult;
import com.christina.engine.routing.manager.RoutingStrategyManager;
import com.christina.engine.routing.model.RoutingDecision;
import com.christina.engine.routing.strategy.RoutingStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;

/**
 * 路由处理器
 * 负责使用策略模式选择合适的服务路由策略并执行路由决策
 */
@Component
public class RoutingProcessor extends AbstractRequestProcessor {
    
    private static final String PROCESSOR_NAME = "RoutingProcessor";
    private static final int PROCESSOR_ORDER = 500; // 在决策处理器之后执行
    
    private final RoutingStrategyManager routingStrategyManager;
    
    @Autowired
    public RoutingProcessor(RoutingStrategyManager routingStrategyManager) {
        super(PROCESSOR_NAME, PROCESSOR_ORDER);
        this.routingStrategyManager = routingStrategyManager;
    }
    
    @Override
    protected ProcessingResult doProcess(ProcessingContext context) {
        logger.debug("Starting routing decision for requestId: {}", context.getRequestId());
        
        try {
            // 获取识别的意图
            Intent recognizedIntent = context.getRecognizedIntent();
            if (recognizedIntent == null) {
                throw new IllegalStateException("No recognized intent found for routing");
            }
            
            // 选择路由策略
            RoutingStrategy selectedStrategy = selectRoutingStrategy(recognizedIntent, context);
            
            // 执行路由决策
            RoutingDecision routingDecision = makeRoutingDecision(recognizedIntent, context, selectedStrategy);
            
            // 验证路由决策
            validateRoutingDecision(routingDecision);
            
            // 评估路由决策质量
            double routingQuality = evaluateRoutingQuality(routingDecision, recognizedIntent);
            
            // 将路由决策存储到处理上下文
            context.setProcessingData("routingDecision", routingDecision);
            context.setProcessingData("selectedStrategy", selectedStrategy.getClass().getSimpleName());
            context.setProcessingData("routingQuality", routingQuality);
            
            // 如果路由质量较低，记录警告
            if (routingQuality < 0.6) {
                logger.warn("Low quality routing decision for requestId: {}, quality: {}, service: {}", 
                        context.getRequestId(), routingQuality, routingDecision.getTargetService());
            }
            
            logger.debug("Routing decision completed for requestId: {}, strategy: {}, service: {}, confidence: {}", 
                    context.getRequestId(), selectedStrategy.getClass().getSimpleName(), 
                    routingDecision.getTargetService(), routingDecision.getConfidence());
            
            return ProcessingResult.builder()
                    .success(true)
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("routingDecision", routingDecision)
                    .resultData("targetService", routingDecision.getTargetService())
                    .resultData("confidence", routingDecision.getConfidence())
                    .resultData("selectedStrategy", selectedStrategy.getClass().getSimpleName())
                    .resultData("routingQuality", routingQuality)
                    .build();
                    
        } catch (Exception e) {
            logger.error("Error during routing decision for requestId: {}", context.getRequestId(), e);
            throw e;
        }
    }
    
    /**
     * 选择路由策略
     */
    private RoutingStrategy selectRoutingStrategy(Intent intent, ProcessingContext context) {
        try {
            RoutingStrategy strategy = routingStrategyManager.selectStrategy(intent, context);
            
            if (strategy == null) {
                logger.warn("No routing strategy selected for intent: {}, using fallback", intent.getType());
                return createFallbackStrategy();
            }
            
            logger.debug("Selected routing strategy: {} for intent: {}", 
                    strategy.getClass().getSimpleName(), intent.getType());
            
            return strategy;
            
        } catch (Exception e) {
            logger.error("Error selecting routing strategy for intent: {}", intent.getType(), e);
            return createFallbackStrategy();
        }
    }
    
    /**
     * 执行路由决策
     */
    private RoutingDecision makeRoutingDecision(Intent intent, ProcessingContext context, RoutingStrategy strategy) {
        try {
            RoutingDecision decision = strategy.route(intent, context);
            
            // 如果决策置信度太低，尝试使用备选策略
            if (decision.getConfidence() < 0.4) {
                logger.debug("Primary routing decision has low confidence: {}, trying alternative", 
                        decision.getConfidence());
                
                RoutingDecision alternativeDecision = tryAlternativeRouting(intent, context);
                if (alternativeDecision.getConfidence() > decision.getConfidence()) {
                    logger.debug("Using alternative routing decision with higher confidence");
                    return alternativeDecision;
                }
            }
            
            return decision;
            
        } catch (Exception e) {
            logger.error("Error making routing decision with strategy: {}", 
                    strategy.getClass().getSimpleName(), e);
            return createFallbackRoutingDecision(intent);
        }
    }
    
    /**
     * 验证路由决策
     */
    private void validateRoutingDecision(RoutingDecision decision) {
        if (decision == null) {
            throw new IllegalStateException("Routing decision cannot be null");
        }
        
        if (decision.getTargetService() == null || decision.getTargetService().trim().isEmpty()) {
            throw new IllegalStateException("Target service cannot be null or empty");
        }
        
        if (decision.getConfidence() < 0.0 || decision.getConfidence() > 1.0) {
            throw new IllegalStateException("Routing confidence must be between 0.0 and 1.0");
        }
        
        // 验证目标服务是否为已知的服务类型
        if (!isValidServiceType(decision.getTargetService())) {
            logger.warn("Unknown target service type: {}", decision.getTargetService());
        }
    }
    
    /**
     * 检查是否为有效的服务类型
     */
    private boolean isValidServiceType(String serviceType) {
        return serviceType != null && 
               (serviceType.equals("travel") || 
                serviceType.equals("chat") || 
                serviceType.equals("user") || 
                serviceType.equals("notification") ||
                serviceType.equals("task") ||
                serviceType.equals("help") ||
                serviceType.equals("human") ||
                serviceType.equals("fallback"));
    }
    
    /**
     * 评估路由决策质量
     */
    private double evaluateRoutingQuality(RoutingDecision decision, Intent intent) {
        double baseScore = decision.getConfidence();
        
        // 根据意图与服务的匹配度调整分数
        double intentServiceMatchScore = calculateIntentServiceMatchScore(intent, decision.getTargetService());
        
        // 根据决策理由的完整性调整分数
        double reasoningScore = decision.getReasoning() != null && !decision.getReasoning().trim().isEmpty() ? 0.8 : 0.4;
        
        // 综合评分
        return (baseScore * 0.6 + intentServiceMatchScore * 0.3 + reasoningScore * 0.1);
    }
    
    /**
     * 计算意图与服务的匹配分数
     */
    private double calculateIntentServiceMatchScore(Intent intent, String targetService) {
        Intent.IntentType intentType = intent.getType();
        
        return switch (intentType) {
            case TRAVEL_PLANNING, TRAVEL_BOOKING, TRAVEL_INQUIRY, TRAVEL_MODIFICATION, TRAVEL_CANCELLATION -> 
                "travel".equals(targetService) ? 1.0 : 0.3;
            case GENERAL_CHAT, QUESTION_ANSWER, RECOMMENDATION -> 
                "chat".equals(targetService) ? 1.0 : 0.4;
            case USER_REGISTRATION, USER_LOGIN, USER_PROFILE -> 
                "user".equals(targetService) ? 1.0 : 0.2;
            case TASK_CREATION, TASK_QUERY, TASK_UPDATE -> 
                "task".equals(targetService) ? 1.0 : 0.3;
            case NOTIFICATION_SETTING, REMINDER_SETTING -> 
                "notification".equals(targetService) ? 1.0 : 0.3;
            case HELP_REQUEST -> 
                "help".equals(targetService) ? 1.0 : 0.5;
            case COMPLAINT -> 
                "human".equals(targetService) ? 1.0 : 0.4;
            default -> 0.5; // 未知意图的默认匹配分数
        };
    }
    
    /**
     * 尝试备选路由策略
     */
    private RoutingDecision tryAlternativeRouting(Intent intent, ProcessingContext context) {
        // 获取所有已注册的策略
        var strategies = routingStrategyManager.getRegisteredStrategies();
        
        for (RoutingStrategy strategy : strategies) {
            if (strategy.supports(intent)) {
                try {
                    RoutingDecision decision = strategy.route(intent, context);
                    if (decision.getConfidence() >= 0.4) {
                        logger.debug("Alternative strategy {} provided better decision", 
                                strategy.getClass().getSimpleName());
                        return decision;
                    }
                } catch (Exception e) {
                    logger.debug("Alternative strategy {} failed: {}", 
                            strategy.getClass().getSimpleName(), e.getMessage());
                }
            }
        }
        
        // 如果所有策略都失败，返回基于意图的简单路由
        return createSimpleIntentBasedRouting(intent);
    }
    
    /**
     * 创建基于意图的简单路由决策
     */
    private RoutingDecision createSimpleIntentBasedRouting(Intent intent) {
        String targetService = getDefaultServiceForIntent(intent.getType());
        
        return RoutingDecision.builder()
                .targetService(targetService)
                .confidence(0.6)
                .reasoning("基于意图类型的简单路由决策")
                .executionParameters(new HashMap<>())
                .build();
    }
    
    /**
     * 根据意图类型获取默认服务
     */
    private String getDefaultServiceForIntent(Intent.IntentType intentType) {
        return switch (intentType) {
            case TRAVEL_PLANNING, TRAVEL_BOOKING, TRAVEL_INQUIRY, TRAVEL_MODIFICATION, TRAVEL_CANCELLATION -> "travel";
            case GENERAL_CHAT, QUESTION_ANSWER, RECOMMENDATION -> "chat";
            case USER_REGISTRATION, USER_LOGIN, USER_PROFILE -> "user";
            case TASK_CREATION, TASK_QUERY, TASK_UPDATE -> "task";
            case NOTIFICATION_SETTING, REMINDER_SETTING -> "notification";
            case HELP_REQUEST -> "help";
            case COMPLAINT -> "human";
            default -> "chat"; // 默认路由到聊天服务
        };
    }
    
    /**
     * 创建兜底路由决策
     */
    private RoutingDecision createFallbackRoutingDecision(Intent intent) {
        String fallbackService = getDefaultServiceForIntent(intent.getType());
        
        return RoutingDecision.builder()
                .targetService(fallbackService)
                .confidence(0.3)
                .reasoning("路由策略失败，使用兜底路由")
                .executionParameters(new HashMap<>())
                .build();
    }
    
    /**
     * 创建兜底路由策略
     */
    private RoutingStrategy createFallbackStrategy() {
        return new RoutingStrategy() {
            @Override
            public RoutingDecision route(Intent intent, ProcessingContext context) {
                return createFallbackRoutingDecision(intent);
            }
            
            @Override
            public boolean supports(Intent intent) {
                return true; // 兜底策略支持所有意图
            }
            
            @Override
            public int getPriority() {
                return Integer.MAX_VALUE; // 最低优先级
            }
            
            @Override
            public String getName() {
                return "FallbackRoutingStrategy";
            }
        };
    }
    
    @Override
    protected void preProcess(ProcessingContext context) {
        super.preProcess(context);
        context.updateState("ROUTING_SERVICE");
    }
    
    @Override
    protected void postProcess(ProcessingContext context, ProcessingResult result) {
        super.postProcess(context, result);
        if (result.isSuccess()) {
            context.updateState("SERVICE_ROUTED");
        } else {
            context.updateState("ROUTING_FAILED");
        }
    }
    
    @Override
    public boolean supports(ProcessingContext context) {
        // 路由处理器需要已识别的意图
        return context != null && 
               context.getOriginalRequest() != null &&
               context.getUserId() != null &&
               context.getSessionId() != null &&
               context.getRecognizedIntent() != null;
    }
    
    @Override
    protected ProcessingResult handleError(ProcessingContext context, Exception exception) {
        logger.warn("Routing failed, using emergency fallback for requestId: {}", 
                context.getRequestId(), exception);
        
        try {
            // 创建紧急路由决策
            Intent intent = context.getRecognizedIntent();
            if (intent == null) {
                intent = createUnknownIntent();
            }
            
            RoutingDecision emergencyDecision = RoutingDecision.builder()
                    .targetService("chat") // 紧急情况下路由到聊天服务
                    .confidence(0.1)
                    .reasoning("路由处理器异常，使用紧急兜底路由")
                    .executionParameters(new HashMap<>())
                    .build();
            
            context.setProcessingData("routingDecision", emergencyDecision);
            context.setProcessingData("routingError", exception.getMessage());
            
            return ProcessingResult.builder()
                    .success(true) // 虽然路由失败，但使用紧急兜底继续处理
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("routingDecision", emergencyDecision)
                    .resultData("targetService", emergencyDecision.getTargetService())
                    .resultData("confidence", emergencyDecision.getConfidence())
                    .resultData("selectedStrategy", "EmergencyFallback")
                    .resultData("emergencyFallbackUsed", true)
                    .resultData("error", exception.getMessage())
                    .build();
                    
        } catch (Exception e) {
            logger.error("Failed to create emergency routing decision for requestId: {}", 
                    context.getRequestId(), e);
            return super.handleError(context, e);
        }
    }
    
    /**
     * 创建未知意图
     */
    private Intent createUnknownIntent() {
        return Intent.builder()
                .type(Intent.IntentType.UNKNOWN)
                .name("未知意图")
                .description("路由处理器错误处理中创建的未知意图")
                .confidence(0.1)
                .parameters(new com.alibaba.fastjson.JSONObject())
                .build();
    }
}